home *** CD-ROM | disk | FTP | other *** search
- //-----------------------------------------------------------------------------
- // File: cdeviceview.cpp
- //
- // Desc: CDeviceView is a window class derived from CFlexWnd. It represents
- // the device view window in which the device and callouts are drawn.
- // Each CDeviceView only represents one view. A device that has more
- // than one view should have a corresponding number of CDeviceView for it.
- //
- // Copyright (C) 1999-2001 Microsoft Corporation. All Rights Reserved.
- //-----------------------------------------------------------------------------
-
- #include "common.hpp"
-
-
- CDeviceView::CDeviceView(CDeviceUI &ui) :
- m_ui(ui),
- m_pbmImage(NULL),
- m_pbmThumb(NULL),
- m_pbmSelThumb(NULL),
- m_SuperState(0),
- m_State(0),
- m_SubState(0),
- m_OldSuperState(0),
- m_OldState(0),
- m_OldSubState(0),
- m_pControlContext(NULL),
- m_ptszImagePath(NULL),
- m_bScrollEnable(FALSE),
- m_nScrollOffset(0),
- m_nViewHeight(g_sizeImage.cy),
- m_bForcePaint(FALSE)
- {
- m_ptNextWLOText.x = m_ptNextWLOText.y = 0;
- }
-
- CDeviceView::~CDeviceView()
- {
- Unpopulate();
- }
-
- CDeviceControl *CDeviceView::NewControl()
- {
- CDeviceControl *pControl = new CDeviceControl(m_ui, *this);
- if (!pControl)
- return NULL;
- m_arpControl.SetAtGrow(m_arpControl.GetSize(), pControl);
- return pControl;
- }
-
- void CDeviceView::Remove(CDeviceControl *pControl)
- {
- if (pControl == NULL)
- return;
-
- int i = pControl->GetControlIndex();
- if (i < 0 || i >= GetNumControls())
- {
- assert(0);
- return;
- }
-
- if (pControl == m_pControlContext)
- m_pControlContext = NULL;
-
- if (m_arpControl[i] != NULL)
- delete m_arpControl[i];
- m_arpControl[i] = NULL;
-
- m_arpControl.RemoveAt(i);
-
- Invalidate();
- }
-
- void CDeviceView::RemoveAll(BOOL bUser)
- {
- m_pControlContext = NULL;
-
- for (int i = 0; i < GetNumControls(); i++)
- {
- if (m_arpControl[i] != NULL)
- delete m_arpControl[i];
- m_arpControl[i] = NULL;
- }
- m_arpControl.RemoveAll();
-
- Invalidate();
- }
-
- void CDeviceView::Unpopulate(BOOL bInternalOnly)
- {
- DisableScrollBar();
-
- m_bScrollEnable = FALSE;
-
- if (m_pbmImage != NULL)
- delete m_pbmImage;
- if (m_pbmThumb != NULL)
- delete m_pbmThumb;
- if (m_pbmSelThumb != NULL)
- delete m_pbmSelThumb;
- m_pbmImage = NULL;
- m_pbmThumb = NULL;
- m_pbmSelThumb = NULL;
- free(m_ptszImagePath);
- m_ptszImagePath = NULL;
-
- if (!bInternalOnly)
- RemoveAll(FALSE);
-
- for (int i = 0; i < m_arpText.GetSize(); i++)
- {
- if (m_arpText[i])
- delete m_arpText[i];
- m_arpText[i] = NULL;
- }
- m_arpText.RemoveAll();
- }
-
- void AssureSize(CBitmap *&pbm, SIZE to)
- {
- if (!pbm)
- return;
-
- SIZE from;
- if (!pbm->GetSize(&from))
- return;
-
- if (from.cx >= to.cx && from.cy >= to.cy)
- return;
-
- CBitmap *nbm = CBitmap::Create(to, RGB(0,0,0));
- if (!nbm)
- return;
-
- HDC hDC = nbm->BeginPaintInto();
- pbm->Draw(hDC);
- nbm->EndPaintInto(hDC);
-
- delete pbm;
- pbm = nbm;
- nbm = NULL;
- }
-
- CBitmap *CDeviceView::GrabViewImage()
- {
- CBitmap *pbm = CBitmap::Create(GetClientSize(), RGB(0, 0, 0), NULL);
- if (!pbm)
- return NULL;
- HDC hDC = pbm->BeginPaintInto();
- if (!hDC)
- {
- delete pbm;
- return NULL;
- }
-
- OnPaint(hDC);
-
- pbm->EndPaintInto(hDC);
-
- return pbm;
- }
-
- void CDeviceView::MakeMissingImages()
- {
- // if (m_pbmImage)
- // AssureSize(m_pbmImage, g_sizeImage);
-
- if (m_pbmThumb == NULL)
- {
- if (m_pbmImage)
- m_pbmThumb = m_pbmImage->CreateResizedTo(g_sizeThumb);
- else
- {
- CBitmap *pbmImage = GrabViewImage();
- if (pbmImage)
- {
- AssureSize(pbmImage, g_sizeImage);
- m_pbmThumb = pbmImage->CreateResizedTo(g_sizeThumb);
- }
- delete pbmImage;
- }
- }
-
- if (m_pbmThumb == NULL)
- return;
-
- if (m_pbmSelThumb == NULL)
- {
- m_pbmSelThumb = m_pbmThumb->Dup();
- if (m_pbmSelThumb != NULL)
- {
- HDC hDC = m_pbmSelThumb->BeginPaintInto();
- {
- CPaintHelper ph(m_ui.m_uig, hDC);
- ph.SetPen(UIP_SELTHUMB);
- ph.Rectangle(0, 0, g_sizeThumb.cx, g_sizeThumb.cy, UIR_OUTLINE);
- }
- m_pbmSelThumb->EndPaintInto(hDC);
- }
- }
- }
-
- void CDeviceView::OnPaint(HDC hDC)
- {
- HDC hBDC = NULL, hODC = NULL;
- CBitmap *pbm = NULL;
-
- if (!InRenderMode())
- {
- hODC = hDC;
- pbm = CBitmap::Create(GetClientSize(), RGB(0, 0, 0), hDC);
- if (pbm != NULL)
- {
- hBDC = pbm->BeginPaintInto();
- if (hBDC != NULL)
- hDC = hBDC;
- }
- }
-
- // Black-fill first
- SIZE fillsz = GetClientSize();
- RECT fillrc = {0, 0, fillsz.cx, fillsz.cy};
- FillRect(hDC, &fillrc, (HBRUSH)GetStockObject(BLACK_BRUSH));
-
- if (m_pbmImage != NULL)
- m_pbmImage->Blend(hDC);
-
- BOOL bScroll = m_bScrollEnable && m_sb.m_hWnd;
- int sdc = 0;
- if (bScroll)
- {
- sdc = SaveDC(hDC);
- OffsetViewportOrgEx(hDC, 0, -m_nScrollOffset + g_iListHeaderHeight, NULL);
- }
- else
- if (m_bScrollEnable)
- {
- sdc = SaveDC(hDC);
- OffsetViewportOrgEx(hDC, 0, g_iListHeaderHeight, NULL);
- }
-
- int miny = 0 + m_nScrollOffset;
- int maxy = g_sizeImage.cy + m_nScrollOffset;
-
- int t, nt = GetNumTexts();
- for (t = 0; t < nt; t++)
- {
- CDeviceViewText *pText = m_arpText[t];
- if (pText != NULL &&
- !(pText->GetMinY() > maxy || pText->GetMaxY() < miny))
- pText->OnPaint(hDC);
- }
-
- BOOL bCFGUIEdit = m_ui.m_uig.InEditMode();
- BOOL bEitherEditMode = bCFGUIEdit;
-
- int c, nc = GetNumControls();
- for (c = 0; c < nc; c++)
- if (m_arpControl[c] != NULL && m_arpControl[c]->HasOverlay() &&
- (m_arpControl[c]->IsHighlighted()
- )
- && (bEitherEditMode || m_arpControl[c]->IsMapped()))
- m_arpControl[c]->DrawOverlay(hDC);
- for (c = 0; c < nc; c++)
- {
- CDeviceControl *pControl = m_arpControl[c];
- if (pControl != NULL && (bEitherEditMode || pControl->IsMapped()) &&
- !(pControl->GetMinY() > maxy || pControl->GetMaxY() < miny))
- pControl->OnPaint(hDC);
- }
-
- if (bScroll || m_bScrollEnable)
- {
- RestoreDC(hDC, sdc);
- sdc = 0;
- }
-
- // Black fill the top portion if this is a list view
- if (bScroll)
- {
- GetClientRect(&fillrc);
- fillrc.bottom = g_iListHeaderHeight;
- FillRect(hDC, &fillrc, (HBRUSH)GetStockObject(BLACK_BRUSH));
- }
-
- // Print out the headers
- TCHAR tszHeader[MAX_PATH];
- // Control column
- if (m_arpText.GetSize())
- {
- CPaintHelper ph(m_ui.m_uig, hDC);
- ph.SetElement(UIE_CALLOUT);
-
- for (int i = 0; i < 2; i++)
- {
- // Check if there are two columns, break out the 2nd iteration if not 2 columns.
- if (i == 1 && !(GetNumControls() > 1 &&
- m_arpControl[0]->GetCalloutMaxRect().top == m_arpControl[1]->GetCalloutMaxRect().top))
- break;
-
- RECT rcheader;
- if (m_arpText.GetSize())
- {
- rcheader = m_arpText[i]->GetRect();
- rcheader.bottom -= rcheader.top;
- rcheader.top = 0;
- LoadString(g_hModule, IDS_LISTHEADER_CTRL, tszHeader, MAX_PATH);
- DrawText(hDC, tszHeader, -1, &rcheader, DT_LEFT|DT_NOPREFIX|DT_CALCRECT);
- if (rcheader.right > m_arpText[i]->GetRect().right)
- rcheader.left -= rcheader.right - m_arpText[i]->GetRect().right;
- DrawText(hDC, tszHeader, -1, &rcheader, DT_LEFT|DT_NOPREFIX);
-
- // Action column
- rcheader = m_arpControl[i]->GetCalloutMaxRect();
- rcheader.bottom -= rcheader.top;
- rcheader.top = 0;
- LoadString(g_hModule, IDS_LISTHEADER_ACTION, tszHeader, MAX_PATH);
- DrawText(hDC, tszHeader, -1, &rcheader, DT_CENTER|DT_NOPREFIX);
- }
- }
- }
-
-
- if (!InRenderMode())
- {
- if (pbm != NULL)
- {
- if (hBDC != NULL)
- {
- pbm->EndPaintInto(hBDC);
- pbm->Draw(hODC);
- }
- delete pbm;
- }
- }
- }
-
- int CDeviceView::GetNumControls()
- {
- return m_arpControl.GetSize();
- }
-
- CDeviceControl *CDeviceView::GetControl(int nControl)
- {
- if (nControl >= 0 && nControl < GetNumControls())
- return m_arpControl[nControl];
- else
- return NULL;
- }
-
- CBitmap *CDeviceView::GetImage(DVIMAGE dvi)
- {
- switch (dvi)
- {
- case DVI_IMAGE: return m_pbmImage;
- case DVI_THUMB: return m_pbmThumb;
- case DVI_SELTHUMB: return m_pbmSelThumb;
-
- default:
- return NULL;
- }
- }
-
- void CDeviceView::OnMouseOver(POINT point, WPARAM wParam)
- {
- if (m_bScrollEnable && m_sb.m_hWnd)
- point.y += m_nScrollOffset;
-
-
- // Check if we are over a control
- POINT adjPt = point;
- if (m_bScrollEnable) adjPt.y -= g_iListHeaderHeight;
- int c, nc = GetNumControls();
- for (c = 0; c < nc; c++)
- if (m_arpControl[c] != NULL && m_arpControl[c]->HitTest(adjPt) != DCHT_NOHIT)
- {
- m_arpControl[c]->OnMouseOver(adjPt);
- return;
- }
-
- // Check if we are over a viewtext
- nc = GetNumTexts();
- for (c = 0; c < nc; c++)
- if (m_arpText[c] != NULL && m_arpText[c]->HitTest(adjPt) != DCHT_NOHIT)
- {
- m_arpText[c]->OnMouseOver(adjPt);
- return;
- }
-
- CFlexWnd::s_ToolTip.SetEnable(FALSE);
-
- DEVICEUINOTIFY uin;
- uin.msg = DEVUINM_MOUSEOVER;
- uin.from = DEVUINFROM_VIEWWND;
- uin.mouseover.point = point;
- m_ui.Notify(uin);
- }
-
- void CDeviceView::OnClick(POINT point, WPARAM wParam, BOOL bLeft)
- {
- if (m_bScrollEnable && m_sb.m_hWnd)
- point.y += m_nScrollOffset;
-
-
- POINT adjPt = point;
- if (m_bScrollEnable) adjPt.y -= g_iListHeaderHeight;
- int c, nc = GetNumControls();
- for (c = 0; c < nc; c++)
- // adjPt is the adjust click point for scrolling list view
- if (m_arpControl[c] != NULL && m_arpControl[c]->HitTest(adjPt) != DCHT_NOHIT)
- {
- m_arpControl[c]->OnClick(adjPt, bLeft);
- return;
- }
-
- {
- for (c = 0; c < GetNumTexts(); ++c)
- if (m_arpControl[c] != NULL && m_arpText[c] != NULL)
- {
- RECT rc = m_arpText[c]->GetRect();
- if (PtInRect(&rc, adjPt))
- {
- m_arpControl[c]->OnClick(adjPt, bLeft);
- return;
- }
- }
- }
-
-
- // Send notification
- DEVICEUINOTIFY uin;
- uin.msg = DEVUINM_CLICK;
- uin.from = DEVUINFROM_VIEWWND;
- uin.click.bLeftButton = bLeft;
- m_ui.Notify(uin);
- }
-
- void CDeviceView::OnDoubleClick(POINT point, WPARAM wParam, BOOL bLeft)
- {
- if (m_bScrollEnable && m_sb.m_hWnd)
- point.y += m_nScrollOffset;
-
- POINT adjPt = point;
- if (m_bScrollEnable) adjPt.y -= g_iListHeaderHeight;
- int c, nc = GetNumControls();
- for (c = 0; c < nc; c++)
- if (m_arpControl[c] != NULL && m_arpControl[c]->HitTest(adjPt) != DCHT_NOHIT)
- {
- m_arpControl[c]->OnClick(adjPt, bLeft, TRUE);
- return;
- }
-
- for (c = 0; c < GetNumTexts(); ++c)
- if (m_arpControl[c] != NULL && m_arpText[c] != NULL)
- {
- RECT rc = m_arpText[c]->GetRect();
- if (PtInRect(&rc, adjPt))
- {
- m_arpControl[c]->OnClick(adjPt, bLeft, TRUE);
- return;
- }
- }
-
- DEVICEUINOTIFY uin;
- uin.msg = DEVUINM_DOUBLECLICK;
- uin.from = DEVUINFROM_VIEWWND;
- uin.click.bLeftButton = bLeft;
- m_ui.Notify(uin);
- }
-
- void CDeviceView::OnWheel(POINT point, WPARAM wParam)
- {
- if (!m_bScrollEnable) return;
-
- if (m_sb.GetMin() == m_sb.GetMax()) return;
-
- int nPage = MulDiv(m_sb.GetPage(), 9, 10) >> 1; // Half a page at a time
-
- if ((int)wParam >= 0)
- m_sb.AdjustPos(-nPage);
- else
- m_sb.AdjustPos(nPage);
-
- m_nScrollOffset = m_sb.GetPos();
- Invalidate();
- }
-
-
- BOOL CDeviceView::DoesCalloutExistForOffset(DWORD dwOfs)
- {
- return DoesCalloutOtherThanSpecifiedExistForOffset(NULL, dwOfs);
- }
-
- BOOL CDeviceView::DoesCalloutOtherThanSpecifiedExistForOffset(CDeviceControl *pOther, DWORD dwOfs)
- {
- int nc = GetNumControls();
- for (int i = 0; i < nc; i++)
- {
- CDeviceControl *pControl = GetControl(i);
- if (pControl == NULL || pControl == pOther)
- continue;
- if (!pControl->IsOffsetAssigned())
- continue;
- if (pControl->GetOffset() == dwOfs)
- return TRUE;
- }
- return FALSE;
- }
-
- // This function returns the index of a control with the specified offset
- int CDeviceView::GetIndexFromOfs(DWORD dwOfs)
- {
- for (int i = 0; i < GetNumControls(); ++i)
- if (m_arpControl[i]->GetOffset() == dwOfs)
- return i;
-
- return -1;
- }
-
-
- int CDeviceView::GetViewIndex()
- {
- return m_ui.GetViewIndex(this);
- }
-
-
- BOOL CDeviceView::IsUnassignedOffsetAvailable()
- {
- DIDEVOBJSTRUCT os;
-
- HRESULT hr = FillDIDeviceObjectStruct(os, m_ui.m_lpDID);
- if (FAILED(hr))
- return FALSE;
-
- if (os.nObjects < 1)
- return FALSE;
-
- assert(os.pdoi);
- if (!os.pdoi)
- return FALSE;
-
- for (int i = 0; i < os.nObjects; i++)
- {
- const DIDEVICEOBJECTINSTANCEW &o = os.pdoi[i];
-
- if (!DoesCalloutExistForOffset(o.dwOfs))
- return TRUE;
- }
-
- return FALSE;
- }
-
- CDeviceViewText *CDeviceView::AddText(
- HFONT f, COLORREF t, COLORREF b, const RECT &r, LPCTSTR text)
- {
- CDeviceViewText *pText = NewText();
- if (!pText)
- return NULL;
-
- pText->SetLook(f, t, b);
- pText->SetRect(r);
- pText->SetText(text);
-
- return pText;
- }
-
- CDeviceViewText *CDeviceView::AddText(
- HFONT f, COLORREF t, COLORREF b, const POINT &p, LPCTSTR text)
- {
- CDeviceViewText *pText = NewText();
- if (!pText)
- return NULL;
-
- pText->SetLook(f, t, b);
- pText->SetPosition(p);
- pText->SetTextAndResizeTo(text);
-
- return pText;
- }
-
- CDeviceViewText *CDeviceView::AddWrappedLineOfText(
- HFONT f, COLORREF t, COLORREF b, LPCTSTR text)
- {
- CDeviceViewText *pText = NewText();
- if (!pText)
- return NULL;
-
- pText->SetLook(f, t, b);
- pText->SetPosition(m_ptNextWLOText);
- pText->SetTextAndResizeToWrapped(text);
-
- m_ptNextWLOText.y += pText->GetHeight();
-
- return pText;
- }
-
- CDeviceViewText *CDeviceView::NewText()
- {
- CDeviceViewText *pText = new CDeviceViewText(m_ui, *this);
- if (!pText)
- return NULL;
- m_arpText.SetAtGrow(m_arpText.GetSize(), pText);
- return pText;
- }
-
- int CDeviceView::GetNumTexts()
- {
- return m_arpText.GetSize();
- }
-
- CDeviceViewText *CDeviceView::GetText(int nText)
- {
- if (nText < 0 || nText >= GetNumTexts())
- return NULL;
- return m_arpText[nText];
- }
-
- void CDeviceView::SetImage(CBitmap *&refpbm)
- {
- delete m_pbmImage;
- m_pbmImage = refpbm;
- refpbm = NULL;
- MakeMissingImages();
- Invalidate();
- }
-
- void CDeviceView::SetImagePath(LPCTSTR tszPath)
- {
- if (m_ptszImagePath)
- free(m_ptszImagePath);
- m_ptszImagePath = NULL;
-
- if (tszPath)
- m_ptszImagePath = _tcsdup(tszPath);
- }
-
- void CDeviceView::CalcDimensions()
- {
- // go through all texts and controls to find the max y coord
- int max = g_sizeImage.cy - g_iListHeaderHeight;
- int i = 0;
- for (; i < GetNumTexts(); i++)
- {
- CDeviceViewText *pText = GetText(i);
- if (!pText)
- continue;
- int ty = pText->GetMaxY();
- if (ty > max)
- max = ty;
- }
- for (i = 0; i < GetNumControls(); i++)
- {
- CDeviceControl *pControl = GetControl(i);
- if (!pControl)
- continue;
- int cy = pControl->GetMaxY();
- if (cy > max)
- max = cy;
- }
-
- // set
- m_nViewHeight = max;
- m_nScrollOffset = 0;
-
- // enable scrollbar if view height more than window size
- if (m_nViewHeight > g_sizeImage.cy - g_iListHeaderHeight)
- EnableScrollBar();
- }
-
- void CDeviceView::DisableScrollBar()
- {
- if (!m_sb.m_hWnd)
- return;
-
- m_sb.Destroy();
- }
-
- void CDeviceView::EnableScrollBar()
- {
- if (m_sb.m_hWnd)
- return;
-
- FLEXSCROLLBARCREATESTRUCT cs;
- cs.dwSize = sizeof(cs);
- cs.dwFlags = FSBF_VERT;
- cs.min = 0;
- cs.max = m_nViewHeight;
- cs.page = g_sizeImage.cy - g_iListHeaderHeight;
- cs.pos = m_nScrollOffset;
- cs.hWndParent = m_hWnd;
- cs.hWndNotify = m_hWnd;
- RECT rect = {g_sizeImage.cx - DEFAULTVIEWSBWIDTH, g_iListHeaderHeight, g_sizeImage.cx, g_sizeImage.cy};
- cs.rect = rect;
- cs.bVisible = TRUE;
- m_sb.SetColors(
- m_ui.m_uig.GetBrushColor(UIE_SBTRACK),
- m_ui.m_uig.GetBrushColor(UIE_SBTHUMB),
- m_ui.m_uig.GetPenColor(UIE_SBBUTTON));
- m_sb.Create(&cs);
- }
-
- LRESULT CDeviceView::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- switch (msg)
- {
- case WM_PAINT:
- m_bForcePaint = TRUE;
- return CFlexWnd::WndProc(hWnd, msg, wParam, lParam);
-
- case WM_FLEXVSCROLL:
- {
- int code = (int)wParam;
- CFlexScrollBar *pSB = (CFlexScrollBar *)lParam;
- if (!pSB)
- return 0;
-
- int nLine = 5;
- int nPage = MulDiv(pSB->GetPage(), 9, 10);
-
- switch (code)
- {
- case SB_LINEUP: pSB->AdjustPos(-nLine); break;
- case SB_LINEDOWN: pSB->AdjustPos(nLine); break;
- case SB_PAGEUP: pSB->AdjustPos(-nPage); break;
- case SB_PAGEDOWN: pSB->AdjustPos(nPage); break;
- case SB_THUMBTRACK: pSB->SetPos(pSB->GetThumbPos()); break;
- }
-
- m_nScrollOffset = pSB->GetPos();
-
- Invalidate();
- return 0;
- }
-
- case WM_FLEXHSCROLL:
- assert(0);
- default:
- return CFlexWnd::WndProc(hWnd, msg, wParam, lParam);
- }
- }
-
- void CDeviceView::ScrollToMakeControlVisible(const RECT &rc)
- {
- RECT viewrc;
-
- if (!m_bScrollEnable)
- return;
-
- GetClientRect(&viewrc);
- viewrc.bottom -= g_iListHeaderHeight;
- viewrc.top += m_nScrollOffset;
- viewrc.bottom += m_nScrollOffset;
-
- // If scroll enabled, we scroll the view to make the control visible if not already so.
- if (m_bScrollEnable && m_sb.m_hWnd &&
- !(viewrc.left <= rc.left &&
- viewrc.right >= rc.right &&
- viewrc.top <= rc.top &&
- viewrc.bottom >= rc.bottom))
- {
- // If the callout is below the view window, scroll so it shows up at the bottom of the window.
- if (viewrc.bottom < rc.bottom)
- m_sb.SetPos(m_sb.GetPos() + rc.bottom - viewrc.bottom);
- else
- m_sb.SetPos(rc.top);
- m_nScrollOffset = m_sb.GetPos();
- Invalidate();
- }
- }
-
- void CDeviceView::SwapControls(int i, int j)
- {
- RECT rect;
- CDeviceControl *pTmpControl;
- CDeviceViewText *pTmpViewText;
-
- pTmpControl = m_arpControl[i];
- m_arpControl[i] = m_arpControl[j];
- m_arpControl[j] = pTmpControl;
- pTmpViewText = m_arpText[i];
- m_arpText[i] = m_arpText[j];
- m_arpText[j] = pTmpViewText;
- // Swap the rect back so everything will display properly.
- rect = m_arpControl[i]->GetCalloutMaxRect();
- m_arpControl[i]->SetCalloutMaxRect(m_arpControl[j]->GetCalloutMaxRect());
- m_arpControl[j]->SetCalloutMaxRect(rect);
- rect = m_arpText[i]->GetRect();
- m_arpText[i]->SetRect(m_arpText[j]->GetRect());
- m_arpText[j]->SetRect(rect);
- // Exchange the text rect width, so the correct width stays with the correct text.
- RECT rc1 = m_arpText[i]->GetRect();
- RECT rc2 = m_arpText[j]->GetRect();
- // Store rc1's new width first
- int iTempWidth = rc1.right - (rc2.right - rc2.left);
- rc2.left = rc2.right - (rc1.right - rc1.left); // Adjust rc2's width
- rc1.left = iTempWidth; // Adjust rc1's width
- m_arpText[i]->SetRect(rc1);
- m_arpText[j]->SetRect(rc2);
- }
-
- // Implements a simple selection sort algorithm to sort the control array and viewtext array.
- // - iStart is the starting index, inclusive.
- // - iEnd is the last index, exclusive.
- void CDeviceView::SortCallouts(int iStart, int iEnd)
- {
- for (int i = iStart; i < iEnd - 1; ++i)
- {
- DWORD dwSmallestOfs = m_arpControl[i]->GetOffset();
- int iSmallestIndex = i;
- for (int j = i + 1; j < iEnd; ++j)
- if (m_arpControl[j]->GetOffset() < dwSmallestOfs)
- {
- dwSmallestOfs = m_arpControl[j]->GetOffset();
- iSmallestIndex = j;
- }
- // Swap the smallest element with i-th element.
- if (iSmallestIndex != i)
- SwapControls(i, iSmallestIndex);
- }
- }
-
- void CDeviceView::SortAssigned(BOOL bSort)
- {
- // If less than 2 controls, no need for sorting.
- if (m_arpControl.GetSize() < 2)
- return;
-
- int iCalloutX[2] = {m_arpControl[0]->GetMinX(), m_arpControl[1]->GetMinX()}; // Callout X for the two columns
-
- // Sort the text array and control array.
- if (bSort)
- {
- // First move all the assigned controls to the first n elements.
- int iNextAssignedWriteIndex = 0;
- for (int i = 0; i < m_arpControl.GetSize(); ++i)
- if (m_arpControl[i]->HasAction())
- {
- // Swap the controls
- SwapControls(i, iNextAssignedWriteIndex);
- ++iNextAssignedWriteIndex; // Increment the write index
- }
-
- // Sort the two parts now
- SortCallouts(0, iNextAssignedWriteIndex);
- SortCallouts(iNextAssignedWriteIndex, m_arpControl.GetSize());
- } else
- SortCallouts(0, m_arpControl.GetSize());
- }
-
- void CDeviceView::DoOnPaint(HDC hDC)
- {
- // Paint only if we have an update region.
- if (GetUpdateRect(m_hWnd, NULL, FALSE) || m_bForcePaint)
- OnPaint(hDC);
- m_bForcePaint = FALSE;
- }
-